#include "XXXSession.h"
#include "ProtocolModule/XXXMsgManager.h"
#include "SimDriverBoard.h"

XXXSession::XXXSession(std::shared_ptr<tcp::socket> socket) : Session(socket)
{
    std::cout << "XXXSession::XXXSession  create..." << std::endl;
}

XXXSession::~XXXSession()
{}

void XXXSession::Start()
{
    // 获取协议处理管理者。 
    // 注意：hxz 因为这里是具体业务功能的实现，所以可以使用SimDriverBoard项目具体的类。类基类Session就不用引用SimDriverBoard
    m_xxxMsgManager = SimDriverBoard::Instance().GetManager<XXXMsgManager>();       
    if (m_xxxMsgManager == nullptr)
    {
        std::cout << "XXXSession::Start  m_xxxMsgManager == nullptr" << std::endl;
        return;
    }

    m_xxxMsgManager->SetSessionPtr(shared_from_this());

    // start thread 响应任务
    m_thread = std::thread(std::bind(&XXXSession::DoTask, this));

    Session::Start();       // 启动接收任务
}

void XXXSession::Stop()
{
    m_beStop = true;
    m_taskCond.NotifyForVariable();
    m_xxxMsgManager->Reset();
    m_xxxMsgManager = nullptr;
    if (m_thread.joinable())
    {
        m_thread.join();
    }
    Session::Stop();
}

void XXXSession::OnRecv(const char* bufData, size_t len)
{
    BufDataAppend(bufData, len);
}

void XXXSession::DoTask()
{
    // 条件变量等待任务的时间，单次等待时间。目的是给m_beStop有可能执行到，避免无限等到，此类不能退出
    static const int XXXSESSION_TASK_WAIT_TIME = 500;

    while (!m_beStop)
    {
        if (IsMsgListEmpty())
        {
            m_taskCond.WaitForVariable(XXXSESSION_TASK_WAIT_TIME);
            continue;
        }
        else 
        {
            std::string oneMsg = PopMsg();
            if (oneMsg.length() > 0)
            {
                HandleMsg(oneMsg);
            }
        }
    }

    std::cout << "XXXSession::DoTask  exit..." << std::endl;
}

void XXXSession::HandleMsg(const std::string& msg)
{
    if (msg.length() > 0 && m_xxxMsgManager != nullptr)
    {
        m_xxxMsgManager->HandleMsg(msg);            // 最终每个请求，交给XXXMsgManager处理
    }
}


// 缓存数据
void XXXSession::BufDataAppend(const char* bufData, size_t len)
{
    const static int MIN_XXX_MSG_LENGTH = 10;                   // 简单定义一个最小的完整的消息长度，缓存消息大于这个数值，就需要

    std::lock_guard<std::mutex> lock(m_cacheDataMutex);
    m_cacheData.append(bufData, len);


    // hxz 具体通讯需要更具项目需要进行特殊处理。这里是一个简单的例子
    std::string oneMsg;
    while (m_cacheData.length() >= MIN_XXX_MSG_LENGTH)
    {
        oneMsg.clear();
        oneMsg = m_cacheData.substr(0, MIN_XXX_MSG_LENGTH);      // 截取第一条请求消息
        m_cacheData = m_cacheData.substr(MIN_XXX_MSG_LENGTH);
        PushMsg(oneMsg);                                         // 添加消息，并触发响应函数
    }

}

// 清空缓存数据
void XXXSession::ClearBufData()
{
    std::lock_guard<std::mutex> lock(m_cacheDataMutex);
    m_cacheData.clear();
}

// 判断请求队列是否为空
bool XXXSession::IsMsgListEmpty()
{
    std::lock_guard<std::mutex> lock(m_msgListMutex);
    return m_msgList.empty();
}

// 清空请求队列
void XXXSession::ClearMsgList()
{
    std::lock_guard<std::mutex> lock(m_msgListMutex);
    m_msgList.clear();
}

// 添加请求队列
void XXXSession::PushMsg(const std::string& msg)
{
    std::lock_guard<std::mutex> lock(m_msgListMutex);
    m_msgList.push_back(msg);
    m_taskCond.NotifyForVariable();
}

// 取出请求队列的第一个请求
std::string XXXSession::PopMsg()
{
    std::lock_guard<std::mutex> lock(m_msgListMutex);
    if (m_msgList.empty())
    {
        return "";
    }
    std::string msg = m_msgList.front();
    m_msgList.pop_front();
    return msg;
}
